package org.example;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPoolManager {
    private static volatile ThreadPoolManager instance;

    private final ScheduledExecutorService scheduledExecutor;
    private final ExecutorService commonExecutor;

    private ThreadPoolManager() {
        // 创建定时任务线程池（核心线程数根据需求调整）
        this.scheduledExecutor = Executors.newScheduledThreadPool(2, new NamedThreadFactory("Scheduled-Pool"));

        // 创建普通任务线程池
        this.commonExecutor = Executors.newCachedThreadPool(new NamedThreadFactory("Common-Pool"));

        Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
    }

    public static ThreadPoolManager getInstance() {
        if (instance == null) {
            synchronized (ThreadPoolManager.class) {
                if (instance == null) {
                    instance = new ThreadPoolManager();
                }
            }
        }
        return instance;
    }

    public ScheduledExecutorService getScheduledExecutor() {
        return scheduledExecutor;
    }

    public ExecutorService getCommonExecutor() {
        return commonExecutor;
    }

    public void shutdown() {
        System.out.println("Shutting down ThreadPoolManager...");
        scheduledExecutor.shutdown();
        commonExecutor.shutdown();

        try {
            if (!scheduledExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
                scheduledExecutor.shutdownNow();
            }
            if (!commonExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
                commonExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduledExecutor.shutdownNow();
            commonExecutor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

// 命名的线程工厂
class NamedThreadFactory implements ThreadFactory {
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;
    private final ThreadGroup group;

    public NamedThreadFactory(String namePrefix) {
        this.namePrefix = namePrefix;
        SecurityManager s = System.getSecurityManager();
        this.group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
    }

    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r, namePrefix + "-" + threadNumber.getAndIncrement(), 0);
        t.setDaemon(false);
        t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}